home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / lib / fnmatch.c < prev    next >
C/C++ Source or Header  |  1992-04-09  |  4KB  |  184 lines

  1. /* Copyright (C) 1992 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. /* Modified slightly by Brian Berliner <berliner@sun.com> for CVS use */
  20.  
  21. /* IGNORE(@ */
  22. /* #include <ansidecl.h> */
  23. /* @) */
  24. #include <errno.h>
  25. #include <fnmatch.h>
  26.  
  27. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
  28. extern int errno;
  29. #endif
  30.  
  31. #if !__STDC__
  32. #define    const
  33. #endif
  34.  
  35. /* Match STRING against the filename pattern PATTERN, returning zero if
  36.    it matches, nonzero if not.  */
  37. int
  38. #if __STDC__
  39. fnmatch (const char *pattern, const char *string, int flags)
  40. #else
  41. fnmatch (pattern, string, flags)
  42.     char *pattern;
  43.     char *string;
  44.     int flags;
  45. #endif
  46. {
  47.   register const char *p = pattern, *n = string;
  48.   register char c;
  49.  
  50.   if ((flags & ~__FNM_FLAGS) != 0)
  51.     {
  52.       errno = EINVAL;
  53.       return -1;
  54.     }
  55.  
  56.   while ((c = *p++) != '\0')
  57.     {
  58.       switch (c)
  59.     {
  60.     case '?':
  61.       if (*n == '\0')
  62.         return FNM_NOMATCH;
  63.       else if ((flags & FNM_PATHNAME) && *n == '/')
  64.         return FNM_NOMATCH;
  65.       else if ((flags & FNM_PERIOD) && *n == '.' &&
  66.            (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  67.         return FNM_NOMATCH;
  68.       break;
  69.       
  70.     case '\\':
  71.       if (!(flags & FNM_NOESCAPE))
  72.         c = *p++;
  73.       if (*n != c)
  74.         return FNM_NOMATCH;
  75.       break;
  76.       
  77.     case '*':
  78.       if ((flags & FNM_PERIOD) && *n == '.' &&
  79.           (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  80.         return FNM_NOMATCH;
  81.       
  82.       for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  83.         if (((flags & FNM_PATHNAME) && *n == '/') ||
  84.         (c == '?' && *n == '\0'))
  85.           return FNM_NOMATCH;
  86.       
  87.       if (c == '\0')
  88.         return 0;
  89.       
  90.       {
  91.         char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  92.         for (--p; *n != '\0'; ++n)
  93.           if ((c == '[' || *n == c1) &&
  94.           fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
  95.         return 0;
  96.         return FNM_NOMATCH;
  97.       }
  98.       
  99.     case '[':
  100.       {
  101.         /* Nonzero if the sense of the character class is inverted.  */
  102.         register int not;
  103.         
  104.         if (*n == '\0')
  105.           return FNM_NOMATCH;
  106.         
  107.         if ((flags & FNM_PERIOD) && *n == '.' &&
  108.         (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  109.           return FNM_NOMATCH;
  110.         
  111.         not = (*p == '!' || *p == '^');
  112.         if (not)
  113.           ++p;
  114.         
  115.         c = *p++;
  116.         for (;;)
  117.           {
  118.         register char cstart = c, cend = c;
  119.         
  120.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  121.           cstart = cend = *p++;
  122.         
  123.         if (c == '\0')
  124.           /* [ (unterminated) loses.  */
  125.           return FNM_NOMATCH;
  126.         
  127.         c = *p++;
  128.         
  129.         if ((flags & FNM_PATHNAME) && c == '/')
  130.           /* [/] can never match.  */
  131.           return FNM_NOMATCH;
  132.         
  133.         if (c == '-' && *p != ']')
  134.           {
  135.             cend = *p++;
  136.             if (!(flags & FNM_NOESCAPE) && cend == '\\')
  137.               cend = *p++;
  138.             if (cend == '\0')
  139.               return FNM_NOMATCH;
  140.             c = *p++;
  141.           }
  142.         
  143.         if (*n >= cstart && *n <= cend)
  144.           goto matched;
  145.         
  146.         if (c == ']')
  147.           break;
  148.           }
  149.         if (!not)
  150.           return FNM_NOMATCH;
  151.         break;
  152.         
  153.       matched:;
  154.         /* Skip the rest of the [...] that already matched.  */
  155.         while (c != ']')
  156.           {
  157.         if (c == '\0')
  158.           /* [... (unterminated) loses.  */
  159.           return FNM_NOMATCH;
  160.         
  161.         c = *p++;
  162.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  163.           /* 1003.2d11 is unclear if this is right.  %%% */
  164.           ++p;
  165.           }
  166.         if (not)
  167.           return FNM_NOMATCH;
  168.       }
  169.       break;
  170.       
  171.     default:
  172.       if (c != *n)
  173.         return FNM_NOMATCH;
  174.     }
  175.       
  176.       ++n;
  177.     }
  178.  
  179.   if (*n == '\0')
  180.     return 0;
  181.  
  182.   return FNM_NOMATCH;
  183. }
  184.